/*
 * @Description:
 * @Autor: HuiSir<273250950@qq.com>
 * @Date: 2020-08-04 15:14:43
 * @LastEditTime: 2020-08-05 19:14:57
 */
import Vue from 'vue'
import Vuex from 'vuex'
import mod1 from './modules/mod1'

Vue.use(Vuex)

//注意：mutations和actions中的方法只能传递一个参数，多参数用对象传递如
// ctx.commit('setTest', {ag1,ag2})

export default new Vuex.Store({
  //state-全局共享数据集合
  //调用state数据的方法1：在组件中使用 `this.$store.state.test`
  //调用state数据的方法2：在组件中引入 `mapState` 函数，然后将其映射为组件中的computed方法: `...mapState(["test"])`
  state: {
    test: 'Welcome to Your Vue.js App',
    userInfo: Object
  },
  //mutations-修改 state 中的数据(mutations-改变)，只有 mutations 有权修改 state 中的数据
  //调用 mutations 中函数的方法1：在组件中使用 `this.$store.commit("setTest",str)` ，其中str为所传的参数，也可以选择不传参
  //调用 mutations 中函数的方法2：在组件中引入 `mapMutations` 函数，然后将其映射为组件中的 methods 方法: `...mapMutations(["setTest"])`
  //注意：mutations 的函数中不能写异步代码，如定时器和请求。异步代码会导致调试器失效（vue-devtool），处理异步任务请使用actions
  mutations: {
    setTest(state, str) {
      //这里传入state数据集和私有参数
      state.test = str
    },
    setUserInfo(state, obj) {
      //这里传入state数据集和私有参数
      state.userInfo = obj
    }
  },
  //actions-执行异步操作如ajax请求或定时器。
  //使用时如果要操作数据，不能直接操作 state 中的数据，必须通过还是要通过 `ctx.commit()` 触发某个 mutations 中的方法来间接改变数据（只有 mutations 有权修改 state 中的数据）
  //调用 actions 中的函数的方法1：在组件中使用 `this.$store.dispatch("setTestAsync",str)` ，其中str为所传的参数，也可以选择不传参（dispatch - 触发）
  //调用 actions 中的函数的方法2：在组件中引入 `mapActions` ，然后将其映射为组件中的 methods 方法: `...mapActions(["setTestAsync"])`
  actions: {
    //模拟异步操作-定时器
    setTestAsync(ctx, str) {
      //这里传入上下文 context 参数和私有参数
      setTimeout(() => {
        ctx.commit('setTest', str) //通过 `ctx.commit()` 触发某个 mutations 中的方法来间接改变数据
      }, 1000)
    },
    //模拟异步操作-ajax请求
    //这里使用解构直接将 commit 和 dispatch 方法拿过来，简单快捷
    //这里使用 async/await 方法进行异步请求，简单方便
    async getUserInfo({ commit, dispatch }, data) {
      let res = await dispatch('getUserApi') //这里可以换成ajax请求
      commit('setUserInfo', res)
    },
    //模拟接口请求
    getUserApi() {
      return {
        name: 'zhangsan',
        age: 18
      }
    }
  },
  //getters-用于包装 state 数据，类似于组件中的 computed 方法。
  //调用方法1：在组件中直接使用 `this.$store.getters.test2`
  //调用方法2：在组件中引入 `mapGetters` 然后将其映射为组件中的 computed 方法: `...mapGetters(["test2"])`
  getters: {
    //这里传入 state 数据集
    test2: state => state.test + '!!!'
  },
  //分模块-一般项目无需使用vuex自带带模块，因为不会很复杂。可以自定义一些普通模块（如将不同类型的state数据或者不同类型的方法分出去），然后引入到本文件中
  //如果使用 modules 模块化引入，会在 state 中增加相应 模块名 为字段，值为该模块中的 state 集合
  modules: {
    mod1
  }
})
